<template>
  <view>
    <SearchForm
      :options="formOptions"
      :multiple="multiple"
      :quick-search-data="quickSearchData"
      :custom-first="customFirst"
      :check-all="checkAll"
      @get-form-model="init"
      @search-refresh="search"
      @search-reset="reset"
    >
      <template #multiple>
        <u-checkbox-group v-model="checkFlag" :active-color="globalTheme.basicColor.primary" @change="checkAll">
          <u-checkbox shape="circle" label="全选" name="全选" />
        </u-checkbox-group>
      </template>
      <template #customFirst>
        <slot name="searchCustomFirst"></slot>
      </template>
    </SearchForm>
    <slot name="top"></slot>
    <view class="m-table pt8" v-if="displayTableData?.length">
      <scroll-view
        :scroll-y="true"
        class="content-box"
        :style="setScrollStyle(useOtherHeight)"
        refresher-enabled
        :refresher-triggered="pullToRefreshLoading"
        @scrolltolower="bottomLoading"
        @refresherrefresh="getTableList('down')"
      >
        <view v-for="(item, index) of displayTableData" :key="item.id || index" class="table-item">
          <!-- v-waterMarker="useWaterMarkerParams" -->
          <view v-for="(head, key) in tableColumns" :key="key" @tap.prevent="skipPage(item)">
            <view v-if="key <= 1" class="title">
              <view v-if="key === 0" class="title-1">
                {{ item[head.prop as string] }}
                <!-- 特殊字段 -->
                <view v-if="specialField && item[specialField]" class="special-field">
                  {{ item[specialField] }}
                </view>
                <!-- 标识 -->
                <text v-if="item.statusName" class="ml-10 status-name" :class="item?.statusType">
                  {{ item.statusName }}
                </text>
              </view>
              <!-- 第二行内容 -->
              <view v-if="key === 1" class="title-2">
                <view class="f" :class="item[head.prop as string] ? 'prop' : ''">
                  {{ item[head.prop as string] }}
                  <view class="i">
                    <u-icon
                      v-if="key === 1 && fold"
                      :name="item.fold ? 'arrow-up' : 'arrow-down'"
                      size="14px"
                      :color="globalTheme.basicColor.primary"
                    />
                  </view>
                </view>
                <!-- 是否显示跳转明细按钮  -->
                <view v-if="toDetail" class="to-detail iconfont icon-youjiantou" @tap.prevent.stop="$emit('skipDetail', item)" />
                <!-- 是否显示选择更多按钮 -->
                <view v-if="multiple" :class="isChecked(item.id)" />
              </view>
            </view>

            <view v-else-if="displayRow(item, head, key)" class="table-row" :class="rowLastClass(key, tableColumns)">
              <view class="label" :style="labelStyle()">
                {{ head.label }}
              </view>
              <view class="value" :style="valueStyle(head, item)">
                <view class="v">
                  {{ item[head.prop as string] || "--" }}
                </view>
              </view>
            </view>
          </view>
          <slot name="bottom" :item="item" :index="index"></slot>
        </view>
        <uni-load-more v-if="displayLoadMore" :status="loadingStatus" />
      </scroll-view>
    </view>
    <!-- 加载完没有数据显示 -->
    <NoTableData v-else-if="!loading" :is-add-permission="displayAddBtn" @add-page-skip="$emit('addPageSkip')" />
  </view>
</template>
<script setup lang="ts" name="ProTable">
import { ColumnProps, verifySpecialValuesProps } from "./interface/index";

import { useOtherStyle } from "./hooks/otherStyle";
import { searchFromOptionsProp } from "../SearchForm/interface";
export interface ProTableProps {
  columns: ColumnProps[]; // 列配置项  ==> 必传
  data?: any[]; // 静态 table data 数据，若存在则不会使用 requestApi 返回的 data ==> 非必传
  useData?: boolean; // 是否使用 props.data 内数据
  requestApi?: (params: any) => Promise<any>; // 请求表格数据的 api ==> 非必传
  requestAuto?: boolean; // 是否自动执行请求 api ==> 非必传（默认为false）
  requestError?: (params: any) => void; // 表格 api 请求错误监听 ==> 非必传
  dataCallback?: (data: any) => any; // 返回数据的回调函数，可以对数据进行处理 ==> 非必传
  changeSearchParams?: (params: any) => any; // 查询数据前最后一次对参数进行修改 ==> 非必传
  pagination?: boolean; // 是否需要分页组件 ==> 非必传（默认为false）
  initParam?: any; // 初始化请求参数 ==> 非必传（默认为{}）
  // --查询表单相关
  formOptions?: searchFromOptionsProp[];
  quickSearchData?: Array<string | number>;
  customFirst?: boolean; // 是否自定义查询第一项 （默认为false）
  // ------特殊类型--------------
  specialField?: string; // 需要显示在右上角的特殊字段
  specialValue?: string; // 需要特殊标记的值，
  fold?: boolean; //是否折叠数据
  verifySpecialValues?: verifySpecialValuesProps[]; //验证特殊标识字段值 是否显示对应特殊颜色
  toDetail?: boolean; // 是否可以跳转明细页面 （默认为false）
  multiple?: boolean; // 是否可以选择更多 （默认为false）
  labelWidth?: string; // 表格标签宽度
  isAddPermission?: boolean | string; // 是否有新增权限
  otherHeight?: number; //页面除表格外其他高度
  goBackParams?: string; //返回上一级页面携带参数,
  waterMarkerParams?: string; // 水印的宽高
}

// 接受父组件参数，配置默认值
const props = withDefaults(defineProps<ProTableProps>(), {
  columns: () => [],
  quickSearchData: () => [],
  requestAuto: false,
  pagination: false,
  initParam: {},
  toDetail: false,
  multiple: false,
  customFirst: false,
  isAddPermission: false,
  fold: false,
  labelWidth: "150",
  otherHeight: 0,
  goBackParams: ""
});

// 是否显示新增按钮
const displayAddBtn = computed(() => {
  if (typeof props.isAddPermission === "boolean") {
    return props.isAddPermission;
  } else if (typeof props.isAddPermission === "string") {
    console.log(isPermission(props.isAddPermission), "isPermission(props.isRightBtn)");

    return isPermission(props.isAddPermission);
  }
});

const useOtherHeight = computed(() => {
  if (props.otherHeight) return props?.otherHeight;
  return props.formOptions?.length ? 85 : 45;
});

let useWaterMarkerParams = reactive({
  width: 0,
  height: 0
});

const $emit = defineEmits(["skipDetail", "addPageSkip", "getSearchModel", "selectChange"]);

const globalTheme = useThemeStore();

// 显示的表格数据
const displayTableData = computed(() => (props.useData ? props.data : tableData.value));

// 选择后数据
const selectChange = (multipleSelection: any[]) => $emit("selectChange", multipleSelection);

// 表格操作 Hooks
const {
  tableData,
  pageable,
  searchParam,
  searchInitParam,
  loading,
  pullToRefreshLoading,
  loadingStatus,
  displayLoadMore,
  checkFlag,
  multipleIds,
  multipleSelection,
  bottomLoading,
  getTableList,
  search,
  reset,
  isChecked,
  setMultipleSelection,
  checkAll
} = useTable(props.requestApi, props.initParam, props.pagination, selectChange, props.dataCallback, props.changeSearchParams);

const { labelStyle, valueStyle, rowLastClass, setScrollStyle } = useOtherStyle(
  props.labelWidth,
  props.specialValue,
  props.verifySpecialValues
);
// 初始化表格数据
onBeforeMount(() => {
  init();
});

const init = (form?) => {
  if (!props.formOptions?.length && props.requestAuto) {
    // 没有查询条件直接调用表格查询
    getTableList();
  }

  if (form) {
    // 有查询条件先获取查询添加在进行查询
    searchParam.value = form;
    searchInitParam.value = JSON.parse(JSON.stringify(form));
    props.requestAuto && reset();

    $emit("getSearchModel", form);
  }

  // 水印宽高处理
  if (props.waterMarkerParams) {
    const arr = props.waterMarkerParams.split(",");
    Object.assign(useWaterMarkerParams, {
      width: arr[0],
      height: arr[1]
    });
  }
  // useWaterMarkerParams.
};

//监听页面 initParam 改化，重新获取表格数据
watch(
  () => props.initParam,
  () => getTableList(),
  { deep: true }
);

// 接收 columns 并设置为响应式
const tableColumns = reactive<ColumnProps[]>(props.columns);

const displayRow = (item, head, key: number) => {
  // 是否需要有值在显示
  let flag = true;
  if (head.isValue) {
    //  如果没有值  false  不显示该字段
    flag = item[head.prop] || false;
  }

  // 折叠
  if (props.fold) {
    // 展开标识打开显示所有
    if (item.fold) {
      return true && flag;
    }
    // 不展开是显示  需要展示的数量
    return key < 8 && flag;
  }

  return flag;
};

// 点击表格主体
const skipPage = row => {
  // 是否展开更多
  if (props.fold) {
    row.fold = !row.fold;
  }
  // 更多选择
  if (props.multiple) setMultipleSelection(row);

  goBackPage(row);
};

// 返回上级页面
const goBackPage = row => {
  if (!props.goBackParams) return;
  const str = props.goBackParams.split(",");
  const params = {};
  for (const key of str) {
    params[key] = row[key] ?? "--";
  }

  uni.$emit("tableBackParams", params);
  uni.navigateBack({
    delta: 1
  });
};
defineExpose({
  tableData,
  pageable,
  searchParam,
  searchInitParam,
  multipleIds,
  multipleSelection,
  getTableList,
  search,
  reset
});
</script>
<style lang="scss" scoped src="./index.scss"></style>
